#include "message_buf.h"
#include <stdlib.h>

DblLinkedList* createDblLinkedList()
 {
	 uint8_t err;
	DblLinkedList *tmp = (DblLinkedList*) OSMemGet(OsMemList,&err);
	tmp->size = 0;
	tmp->head = tmp->tail = tmp->cur = 0;;
	return tmp;
}


void deleteDblLinkedList(DblLinkedList **list)
 {
	Node *tmp = (*list)->head;
	Node *next = NULL;
	while (tmp) {
		next = tmp->next;
		free(tmp);
		tmp = next;
	}
	OSMemPut(OsMemList,*list);//free(*list);
	(*list) = NULL;
}


void pushFront(DblLinkedList *list, void *data)
 {
	 uint8_t err;
	Node *tmp =(Node*) OSMemGet(OsMemBuffer,&err);
	if (tmp == NULL) {
		return;
	}
	memcpy(&tmp->value,(CAN_MSG*)data,sizeof(CAN_MSG));
	tmp->next = list->head;
	tmp->prev = NULL;
	if (list->head) {
		list->head->prev = tmp;
	}
	list->head = tmp;
	
	if (list->tail == NULL) {
		list->tail = tmp;
	}
	list->size++;
}



void* popFront(DblLinkedList *list)
 {
	Node *prev;
	void *tmp = NULL;
	if (list->head == NULL) {
		return NULL;
	}
	
	prev = list->head;
	list->head = list->head->next;
	if (list->head) {
		list->head->prev = NULL;
	}
	if (prev == list->tail) {
		list->tail = NULL;
	}
	memcpy(tmp,&prev->value,sizeof(CAN_MSG));
	OSMemPut(OsMemBuffer,prev);//free(prev);
	
	list->size--;
	return tmp;
}


void pushBack(DblLinkedList *list, void *value)
 {
	 uint8_t err;
	Node *tmp =(Node*) OSMemGet(OsMemBuffer,&err);
	//printf("tmp=%d",tmp);
	if (tmp == NULL) {
		printf("err");
		return;
	}
	memcpy(&tmp->value,(CAN_MSG*)value,sizeof(CAN_MSG));
	//printf("%d  %d",tmp->value.msg_len,tmp->value.msg_data[0]);
	tmp->next = NULL;
	tmp->prev = list->tail;
	if (list->tail) {
		list->tail->next = tmp;
	}
	list->tail = tmp;
	
	if (list->head == NULL) {
		list->head = tmp;
	}
	list->size++;
}



void* popBack(DblLinkedList *list) 
{
	Node *next;
	void *tmp = NULL;
	if (list->tail == NULL) {
		return NULL;
	}
	
	next = list->tail;
	list->tail = list->tail->prev;
	if (list->tail) {
		list->tail->next = NULL;
	}
	if (next == list->head) {
		list->head = NULL;
	}
	memcpy((CAN_MSG*)tmp,&next->value,sizeof(CAN_MSG));
	OSMemPut(OsMemBuffer,next);//free(prev);//free(next);
	
	list->size--;
	return tmp;
}



Node* getNth(DblLinkedList *list, size_t index) 
{
	Node *tmp = list->head;
	size_t i = 0;
	
	while (tmp && i < index) {
		tmp = tmp->next;
		i++;
	}
	
	return tmp;
}



void insert(DblLinkedList *list, size_t index, void *value)
 {
	uint8_t err;
	Node *elm = NULL;
	Node *ins = NULL;
	elm = getNth(list, index);
	if (elm == NULL) {
		return;
	}
	ins = (Node*) OSMemGet(OsMemBuffer,&err);
	memcpy(&ins->value,(CAN_MSG*)value,sizeof(CAN_MSG));
	ins->prev = elm;
	ins->next = elm->next;
	if (elm->next) {
		elm->next->prev = ins;
	}
	elm->next = ins;
	
	if (!elm->prev) {
		list->head = elm;
	}
	if (!elm->next) {
		list->tail = elm;
	}
	
	list->size++;
}

void* deleteNth(DblLinkedList *list, size_t index)
 {
	Node *elm = NULL;
	void *tmp = NULL;
	elm = getNth(list, index);
	if (elm == NULL) {
		return NULL;
	}
	if (elm->prev) {
		elm->prev->next = elm->next;
	}
	if (elm->next) {
		elm->next->prev = elm->prev;
	}
	memcpy((CAN_MSG*)tmp,&elm->value,sizeof(CAN_MSG));
	
	if (!elm->prev) {
		list->head = elm->next;
	}
	if (!elm->next) {
		list->tail = elm->prev;
	}
	
	OSMemPut(OsMemBuffer,elm);//free(elm);
	
	list->size--;
	
	return tmp;
}


void* deleteCurr(DblLinkedList *list)
{
	Node *elm = NULL;
	void *tmp = NULL;
	elm = list->cur;
	if (elm == NULL) {
		return NULL;
	}
	if (elm->prev) {
		elm->prev->next = elm->next;
	}
	if (elm->next) {
		elm->next->prev = elm->prev;
		list->cur = elm->next;
	}
	else
	{
		list->cur = elm->prev;
	}
	//memcpy((CAN_MSG*)tmp,&elm->value,sizeof(CAN_MSG));
	
	if (!elm->prev) {
		list->head = elm->next;
	}
	if (!elm->next) {
		list->tail = elm->prev;
	}
	
	//OSMemPut(OsMemBuffer,elm);//free(elm);
	
	list->size--;
	
	return tmp;
}